import Vue from 'vue'

/**
 * 表单验证
 * @author echo.
 * @version 1.5.0
 **/
const validation = {
  // 非必填情况下,如果值为空,则不进行校验
  // 当出现错误时返回错误消息，否则返回空即为验证通过
  /*
	 formData: Object 表单对象。{key:value,key:value},key==rules.name
	 rules: Array [{name:name,rule:[],msg:[]},{name:name,rule:[],msg:[]}]
			name:name 属性 => 元素的名称
			rule:字符串数组 ["required","isMobile","isEmail","isCarNo","isIdCard","isAmount","isNum","isChinese","isEnglish",isEnAndNo","isSpecial","isEmoji",""isDate","isUrl","isSame:key","range:[1,9]","minLength:9","maxLength:Number"]
			msg:数组 []。 与数组 rule 长度相同,对应的错误提示信息
	*/
  validate: function (formData, rules) {
    for (let item of rules) {
      let key = item.name
      let rule = item.rule
      let msgArr = item.msg
      if (!key || !rule || rule.length === 0 || !msgArr || msgArr.length === 0) {
        continue
      }
      for (let i = 0, length = rule.length; i < length; i++) {
        let ruleItem = rule[i]
        let msg = msgArr[i]
        if (!ruleItem || !msg || (!~rule.indexOf('required') && formData[key].toString().length === 0)) {
          continue
        }
        //数据处理
        let value = null
        if (~ruleItem.indexOf(':')) {
          let temp = ruleItem.split(':')
          ruleItem = temp[0]
          value = temp[1]
        }
        let isError = false
        switch (ruleItem) {
          case 'required':
            isError = validation.isNullOrEmpty(formData[key])
            break
          case 'isMobile':
            isError = !validation.isMobile(formData[key])
            break
          case 'isEmail':
            isError = !validation.isEmail(formData[key])
            break
          case 'isCarNo':
            isError = !validation.isCarNo(formData[key])
            break
          case 'isIdCard':
            isError = !validation.isIdCard(formData[key])
            break
          case 'isAmount':
            isError = !validation.isAmount(formData[key])
            break
          case 'isNum':
            isError = !validation.isNum(formData[key])
            break
          case 'isChinese':
            isError = !validation.isChinese(formData[key])
            break
          case 'isEnglish':
            isError = !validation.isEnglish(formData[key])
            break
          case 'isEnAndNo':
            isError = !validation.isEnAndNo(formData[key])
            break
          case 'isEnOrNo':
            isError = !validation.isEnOrNo(formData[key])
            break
          case 'isSpecial':
            isError = validation.isSpecial(formData[key])
            break
          case 'isEmoji':
            isError = validation.isEmoji(formData[key])
            break
          case 'isDate':
            isError = !validation.isDate(formData[key])
            break
          case 'isUrl':
            isError = !validation.isUrl(formData[key])
            break
          case 'isSame':
            isError = !validation.isSame(formData[key], formData[value])
            break
          case 'range':
            let range = null
            try {
              range = JSON.parse(value)
              if (range.length <= 1) {
                throw new Error('range值传入有误！')
              }
            } catch (e) {
              return 'range值传入有误！'
            }
            isError = !validation.isRange(formData[key], range[0], range[1])
            break
          case 'minLength':
            isError = !validation.minLength(formData[key], value)
            break
          case 'maxLength':
            isError = !validation.maxLength(formData[key], value)
            break
          default:
            break
        }
        if (isError) {
          return msg
        }
      }
    }
    return ''
  },
  isNullOrEmpty: function (value) {
    return value === null || value === '' || value === undefined ? true : false
  },
  isMobile: function (value) {
    return /^(?:13\d|14\d|15\d|16\d|17\d|18\d|19\d)\d{5}(\d{3}|\*{3})$/.test(value)
  },
  isEmail: function (value) {
    return /^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/.test(value)
  },
  isCarNo: function (value) {
    // 新能源车牌
    const xreg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}(([0-9]{5}[DF]$)|([DF][A-HJ-NP-Z0-9][0-9]{4}$))/
    // 旧车牌
    const creg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]{1}$/
    if (value.length === 7) {
      return creg.test(value)
    } else if (value.length === 8) {
      return xreg.test(value)
    } else {
      return false
    }
  },
  isIdCard: function (value) {
    let idCard = value
    if (idCard.length == 15) {
      return this.isValidityBirthBy15IdCard
    } else if (idCard.length == 18) {
      let arrIdCard = idCard.split('')
      if (this.isValidityBirthBy18IdCard(idCard) && this.isTrueValidateCodeBy18IdCard(arrIdCard)) {
        return true
      } else {
        return false
      }
    } else {
      return false
    }
  },
  isTrueValidateCodeBy18IdCard: function (arrIdCard) {
    let sum = 0
    let Wi = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1]
    let valideCode = [1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2]
    if (arrIdCard[17].toLowerCase() == 'x') {
      arrIdCard[17] = 10
    }
    for (let i = 0; i < 17; i++) {
      sum += Wi[i] * arrIdCard[i]
    }
    let valCodePosition = sum % 11
    if (arrIdCard[17] == valideCode[valCodePosition]) {
      return true
    } else {
      return false
    }
  },
  isValidityBirthBy18IdCard: function (idCard18) {
    let year = idCard18.substring(6, 10)
    let month = idCard18.substring(10, 12)
    let day = idCard18.substring(12, 14)
    let tempDate = new Date(year, parseFloat(month) - 1, parseFloat(day))
    if (
      tempDate.getFullYear() != parseFloat(year) ||
      tempDate.getMonth() != parseFloat(month) - 1 ||
      tempDate.getDate() != parseFloat(day)
    ) {
      return false
    } else {
      return true
    }
  },
  isValidityBirthBy15IdCard: function (idCard15) {
    let year = idCard15.substring(6, 8)
    let month = idCard15.substring(8, 10)
    let day = idCard15.substring(10, 12)
    let tempDate = new Date(year, parseFloat(month) - 1, parseFloat(day))

    if (
      tempDate.getYear() != parseFloat(year) ||
      tempDate.getMonth() != parseFloat(month) - 1 ||
      tempDate.getDate() != parseFloat(day)
    ) {
      return false
    } else {
      return true
    }
  },
  isAmount: function (value) {
    //金额，只允许保留两位小数
    return /^([0-9]*[.]?[0-9])[0-9]{0,1}$/.test(value)
  },
  isNum: function (value) {
    //只能为数字
    return /^[0-9]+$/.test(value)
  },
  isChinese: function (value) {
    let reg = /.*[\u4e00-\u9fa5]+.*$/
    return value !== '' && reg.test(value) && !validation.isSpecial(value) && !validation.isEmoji(value)
  },
  isEnglish: function (value) {
    return /^[a-zA-Z]*$/.test(value)
  },
  isEnAndNo: function (value) {
    //8~20位数字和字母组合
    return /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8,20}$/.test(value)
  },
  isEnOrNo: function (value) {
    //英文或者数字
    let reg = /.*[\u4e00-\u9fa5]+.*$/
    let result = true
    if (reg.test(value) || validation.isSpecial(value) || validation.isEmoji(value)) {
      result = false
    }
    return result
  },
  isSpecial: function (value) {
    //是否包含特殊字符
    let regEn = /[`~!@#$%^&*()_+<>?:"{},.\/;'[\]]/im,
      regCn = /[·！#￥（——）：；“”‘、，|《。》？、【】[\]]/im
    if (regEn.test(value) || regCn.test(value)) {
      return true
    }
    return false
  },
  isEmoji: function (value) {
    //是否包含表情
    return /\uD83C[\uDF00-\uDFFF]|\uD83D[\uDC00-\uDE4F]/g.test(value)
  },
  isDate: function (value) {
    //2019-10-12
    const reg = /^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)$/
    return reg.test(value)
  },
  isUrl: function (value) {
    return /^((https?|ftp|file):\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/.test(value)
  },
  isSame: function (value1, value2) {
    return value1 === value2
  },
  isRange: function (value, range1, range2) {
    if (!range1 && range1 != 0 && !range2 && range2 != 0) {
      return true
    } else if (!range1 && range1 != 0) {
      return value <= range2
    } else if (!range2 && range2 != 0) {
      return value >= range1
    } else {
      return value >= range1 && value <= range2
    }
  },
  minLength: function (value, min) {
    return value.length >= Number(min)
  },
  maxLength: function (value, max) {
    return value.length <= Number(max)
  }
}

Vue.prototype.$validation = validation

export default validation
